

/**	
*	
	Doyle Spiral
*/

import ij.ImagePlus;
import ij.plugin.PlugIn;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;

import java.awt.Color;
import java.awt.Polygon;
import java.util.ArrayList;
import java.util.Random; 


import pluginUtils.DoyleCircle;


public class doyle2_ extends ImagePlus implements PlugIn {
	private ImageProcessor primeIP; 
	private int X=2000,Y=2000;
	private Random generator=new Random(); 
	private boolean first=true; 
	
	private void drawCircle(DoyleCircle c){
		int intX=(int)(c.getXcenter()*X);
		int intY=(int)(c.getYcenter()*Y);
		int intR=(int)(c.getRadius()*X); // X ??
		primeIP.drawOval(intX-intR,intY-intR,intR*2,intR*2);
		if(first){
		primeIP.fillOval(intX-5,intY-5,10,10);
		first=false;
		}
		
	}
	
	static private boolean tracable(DoyleCircle c){
		if(c.getXcenter()-c.getRadius()>1) return false; 
		if(c.getXcenter()+c.getRadius()<0)return false; 
		if(c.getYcenter()-c.getRadius()>1) return false; 
		if(c.getYcenter()+c.getRadius()<0)return false; 
		return true; 
	}
	
	public void run(String arg) {
		primeIP = new ColorProcessor(X,Y);
		DoyleCircle.setBounds(0,0);
		double a=2; 
		double  n=3.0; 
		double  m=2.0; 
		//double blog=(n+0.0)/m*Math.log(a); 
		//double b=Math.exp(blog); 
		//double b=Math.pow(a,(n+0.0)/m);
		double b=4; 
		System.out.println(a+" "+b);
		
		// Calcul des angles
		double u[]={1+1/a+b/a,1+1/a+1/b,1+1/b+a/b,1+a+a/b,1+a+b,1+b+b/a};//1+a+a*b en 5eme pos
		double theta[]={Math.acos((u[0]-b/(a*a))/(u[0]+b/(a*a))),
						Math.acos((u[1]-1/(a*b))/(u[1]+1/(a*b))),
						Math.acos((u[2]-a/(b*b))/(u[2]+a/(b*b))),
						Math.acos((u[3]-a*a/b)/(u[3]+a*a/b)),
						Math.acos((u[4]-a*b)/(u[4]+a*b)),
						Math.acos((u[5]-b*b/a)/(u[5]+b*b/a))
		};
		
		// debug-test : calcul d'un angle de rotation
		// Rotation pour le premier sous-cercle
		double uprov=u[5]*b/a; 
		double alpha=Math.acos((uprov-b)/(uprov+b)); 
		System.out.println("alpha "+alpha*180/Math.PI); 
		double rotat=alpha-Math.PI+theta[4]+theta[5]; 
		System.out.println("rotation "+rotat*180/Math.PI);
		
		// deuxieme cercle 
		double uprov2=u[0]*b/a; 
		double gamma=Math.acos((uprov2-1/a)/(uprov2+1/a));
		double rotat2=theta[5]-gamma; 
		System.out.println("gamma :"+gamma*180/Math.PI+" rotat2 "+rotat2*180/Math.PI); 
		
		double radiusCoef[]={b/a,1.0/a,1.0/b,a/b,a,b};
		
		
		double rotationAngle[]=new double[6]; 
		rotationAngle[0]=rotat; 
		rotationAngle[1]=rotat2;
		rotationAngle[2]=-Math.PI+(theta[0]+theta[1]+theta[5]);
		rotationAngle[3]=-Math.PI+(theta[0]+theta[1]+theta[2]); 
		
		
		// cinquieme cercle
		double uprov5=u[4]*a;
		double delta=Math.acos((uprov5-b)/(uprov5+b));
		double beta=Math.PI-(theta[4]+theta[5]); 
		rotationAngle[4]=beta-delta; 
		
		// sixieme cercle
		double uprov6=u[5]*b;
		double eta=Math.acos((uprov6-b/a)/(uprov6+b/a));
		rotationAngle[5]=Math.PI-theta[5]-eta-theta[0];  
		
		Polygon background=new Polygon(new int[]{0,0,X,Y},new int[]{0,X,Y,0},4);
		primeIP.setColor(new Color(0.9f,0.9f,0.82f));
		
		primeIP.fillPolygon(background);
		
		ArrayList<DoyleCircle> todo=new ArrayList<DoyleCircle>();
		ArrayList<DoyleCircle> traces=new ArrayList<DoyleCircle>(); 
		primeIP.setColor(new Color(0.9f,0.0f,0.82f));
		
		/*******************************************************/
		DoyleCircle init=new DoyleCircle(0.5,0.5,0.75,0.05,0,0); 
		drawCircle(init); 
		double theta0=init.getRotation(); 
		for(int i=0;i<6;i++){
			double rad=init.getRadius()*(1+radiusCoef[i]); 
			double nX=init.getXcenter()+rad*Math.cos(theta0);
			double nY=init.getYcenter()+rad*Math.sin(theta0);
			double angle=init.getRotation()+rotationAngle[i]; 
			DoyleCircle c=new DoyleCircle(nX,nY,angle,init.getRadius()*radiusCoef[i],0,0);
			drawCircle(c); 
			double theta1=c.getRotation();
			for(int k=0;k<6;k++){
				double rad1=c.getRadius()*(1+radiusCoef[k]); 
				double nX1=c.getXcenter()+rad1*Math.cos(theta1);
				double nY1=c.getYcenter()+rad1*Math.sin(theta1);
				double angle1=c.getRotation()+rotationAngle[k]; 
				DoyleCircle c1=new DoyleCircle(nX1,nY1,angle1,c.getRadius()*radiusCoef[k],0,0);
				drawCircle(c1);
				double theta2=c1.getRotation();
				if((k==4)&&(i==4)){
				primeIP.setColor(Color.BLUE);
				int intX=(int)(c1.getXcenter()*X);
				int intY=(int)(c1.getYcenter()*Y);
				primeIP.fillOval(intX-5,intY-5,10,10);
				
				}
				for(int l=0;l<6;l++){
					double rad2=c1.getRadius()*(1+radiusCoef[l]); 
					double nX2=c1.getXcenter()+rad2*Math.cos(theta2);
					double nY2=c1.getYcenter()+rad2*Math.sin(theta2);
					double angle2=c1.getRotation()+rotationAngle[l]; 
					DoyleCircle c2=new DoyleCircle(nX2,nY2,angle2,c1.getRadius()*radiusCoef[l],0,0);
					drawCircle(c2);
					theta2+=theta[l]; 
				}
				setProcessor("Verifying", primeIP);
				show();
				System.out.println("i="+i+" k="+k); 
				
				
				primeIP.setColor(new Color(0.9f,0.0f,0.82f)); 
				theta1+=theta[k];
			}	
			theta0+=theta[i];
		}
		
		
		
	
		
		setProcessor("Verifying", primeIP);
		show();
	}	
}
	
	
	